package logger

import (
  "context"
  "fmt"
  "go.uber.org/zap"
  "go.uber.org/zap/zapcore"
  "livefind/global"
  "livefind/initialize/viper"
  "livefind/utils"
  "os"
  "time"
)

var level zapcore.Level
var logger *zap.Logger

func init() {
  // 初始化Viper
  global.GVA_VP = viper.Viper()
}

func init() {
  if ok, _ := utils.PathExists(global.GVA_CONFIG.Zap.Director); !ok { // 判断是否有Director文件夹
    fmt.Printf("create %v directory\n", global.GVA_CONFIG.Zap.Director)
    _ = os.Mkdir(global.GVA_CONFIG.Zap.Director, os.ModePerm)
  }

  switch global.GVA_CONFIG.Zap.Level { // 初始化配置文件的Level
  case "debug":
    level = zap.DebugLevel
  case "info":
    level = zap.InfoLevel
  case "warn":
    level = zap.WarnLevel
  case "error":
    level = zap.ErrorLevel
  case "dpanic":
    level = zap.DPanicLevel
  case "panic":
    level = zap.PanicLevel
  case "fatal":
    level = zap.FatalLevel
  default:
    level = zap.InfoLevel
  }

  if level == zap.DebugLevel || level == zap.ErrorLevel {
    logger = zap.New(getEncoderCore(), zap.AddStacktrace(level))
  } else {
    logger = zap.New(getEncoderCore())
  }
  if global.GVA_CONFIG.Zap.ShowLine {
    logger = logger.WithOptions(zap.AddCaller(), zap.AddCallerSkip(1))
  }
}

// getEncoderConfig 获取zapcore.EncoderConfig
func getEncoderConfig() (config zapcore.EncoderConfig) {
  config = zapcore.EncoderConfig{
    MessageKey:     "message",
    LevelKey:       "level",
    TimeKey:        "time",
    NameKey:        "logger",
    CallerKey:      "caller",
    StacktraceKey:  global.GVA_CONFIG.Zap.StacktraceKey,
    LineEnding:     zapcore.DefaultLineEnding,
    EncodeLevel:    zapcore.LowercaseColorLevelEncoder,
    EncodeTime:     CustomTimeEncoder,
    EncodeDuration: zapcore.SecondsDurationEncoder,
    EncodeCaller:   zapcore.FullCallerEncoder,
  }
  switch {
  case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
    config.EncodeLevel = zapcore.LowercaseLevelEncoder
  case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
    config.EncodeLevel = zapcore.LowercaseColorLevelEncoder
  case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
    config.EncodeLevel = zapcore.CapitalLevelEncoder
  case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
    config.EncodeLevel = zapcore.CapitalColorLevelEncoder
  default:
    config.EncodeLevel = zapcore.LowercaseLevelEncoder
  }
  return config
}

// getEncoder 获取zapcore.Encoder
func getEncoder() zapcore.Encoder {
  if global.GVA_CONFIG.Zap.Format == "json" {
    return zapcore.NewJSONEncoder(getEncoderConfig())
  }
  return zapcore.NewConsoleEncoder(getEncoderConfig())
}

// getEncoderCore 获取Encoder的zapcore.Core
func getEncoderCore() (core zapcore.Core) {
  writer, err := utils.GetWriteSyncer() // 使用file-rotatelogs进行日志分割
  if err != nil {
    fmt.Printf("Get Write Syncer Failed err:%v", err.Error())
    return
  }
  return zapcore.NewCore(getEncoder(), writer, level)
}

// 自定义日志输出时间格式
func CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  enc.AppendString(t.Format(global.GVA_CONFIG.Zap.Prefix + "2006/01/02 - 15:04:05.000"))
}

func Debug(msg string, fields ...zap.Field) {
  logger.Debug(msg, fields...)
}

func Info(msg string, fields ...zap.Field) {
  logger.Info(msg, fields...)
}

func Warn(msg string, fields ...zap.Field) {
  logger.Warn(msg, fields...)
}

func Error(msg string, err error) {
  var fields []zap.Field
  fields = make([]zap.Field, 0, 1)
  fields = append(fields, zap.Error(err))
  logger.Error(msg, fields...)
}

func Fatal(msg string, err error) {
  _ = global.GVA_MONGO.Disconnect(context.TODO())
  logger.Info("Closed MongoDB Server SUCCESS")
  var fields []zap.Field
  fields = make([]zap.Field, 0, 1)
  fields = append(fields, zap.Error(err))
  logger.Fatal(msg, fields...)
}
